

#include <local.h>

void add(vm_vector *, int);
void subtract(vm_vector *, int);
void dot(vm_vector *, int);
void cross(vm_vector *, int);
void inverse(vm_vector *, int);
void magnitude(vm_vector *, int);
void norm(vm_vector *, int);
void project(vm_vector *, int);
void angle(vm_vector *, int);
void print(vm_vector *, int);

void run_operations(unsigned int ops, vm_vector *vects, int vect_len){

  if (ops & FLAG_OP_PRINT){
    print(vects, vect_len);
  }
  if (ops & FLAG_OP_ADD){
    add(vects, vect_len);
  }
  if (ops & FLAG_OP_SUB){
    subtract(vects, vect_len);
  }
  if (ops & FLAG_OP_DOT){
    dot(vects, vect_len);
  }
  if (ops & FLAG_OP_CROSS){
    cross(vects, vect_len);
  }
  if (ops & FLAG_OP_INV){
    inverse(vects, vect_len);
  }
  if (ops & FLAG_OP_MAG){
    magnitude(vects, vect_len);
  }
  if (ops & FLAG_OP_NORM){
    norm(vects, vect_len);
  }
  if (ops & FLAG_OP_PROJECT){
    project(vects, vect_len);
  }
  if (ops & FLAG_OP_ANGLE){
    angle(vects, vect_len);
  }

}

void add(vm_vector *vects, int len){

#ifdef _DEBUG
  printf("Adding vectors; len=%d\n", len);
#endif
  
  vm_vector tmp = vects[0];

  int i = 1;
  for ( ; i < len; i++){
    vm_add(tmp, vects[i], &tmp);
  }
  printf("Result from addition of %d vectors: ", len);
  vm_println(tmp);

}

void subtract(vm_vector *vects, int len){

#ifdef _DEBUG
  printf("Subtracting vectors; len=%d\n", len);
#endif
  
  vm_vector tmp = vects[0];

  int i = 1;
  for ( ; i < len; i++){
    vm_sub(tmp, vects[i], &tmp);
  }
  printf("Result from substraction of %d vectors: ", len);
  vm_println(tmp);

}

void dot(vm_vector *vects, int len){

#ifdef _DEBUG
  printf("Start vector: ");
  vm_println(vects[0]);
  printf("Dotting start vector with %d other vectors.\n", len - 1);
#endif

  if (len < 2){
    printf("Cannot dot less than two vectors; num vects: %d\n", len);
  }

  double tmp;
  int i = 1;
  for ( ; i < len; i++){
    vm_dot(vects[0], vects[i], &tmp);
    vm_print(vects[0]); printf(" . "); vm_print(vects[i]);
    printf(" = %f\n", tmp);
  }

}

void cross(vm_vector *vects, int len){

#ifdef _DEBUG
  printf("Start vector: ");
  vm_println(vects[0]);
  printf("Crossing start vector with %d other vectors.\n", len - 1);
#endif

  if (len < 2){
    printf("Cannot cross less than two vectors; num vects: %d\n", len);
  }

  vm_vector tmp;
  int i = 1;
  for ( ; i < len; i++){
    vm_cross(vects[0], vects[i], &tmp);
    vm_print(vects[0]); printf(" X "); vm_print(vects[i]);
    printf(" = "); vm_println(tmp);
  }

}

void inverse(vm_vector *vects, int len){

#ifdef _DEBUG
  printf("Taking inverse of %d vectors.\n", len);
#endif

  vm_vector tmp;
  int i = 0;
  for ( ; i < len; i++){
    vm_vect_inverse(vects[i], &tmp);
    printf("Inverse of: "); vm_print(vects[i]);
    printf(" = "); vm_println(tmp);
  }

}

void magnitude(vm_vector *vects, int len){

#ifdef _DEBUG
  printf("Taking magnitude of %d vectors.\n", len);
#endif

  int i = 0;
  for ( ; i < len; i++){
    double d = vm_magnitude(vects[i]);
    printf("Magnitude of: "); vm_print(vects[i]);
    printf(" = %f\n", d);
  }

}

void norm(vm_vector *vects, int len){

#ifdef _DEBUG
  printf("Taking norm of %d vectors.\n", len);
#endif

  vm_vector tmp;
  int i = 0;
  for ( ; i < len; i++){
    vm_norm(vects[i], &tmp);
    printf("Norm of: "); vm_print(vects[i]);
    printf(" = "); vm_println(tmp);
  }

}

void project(vm_vector *vects, int len){

#ifdef _DEBUG
  printf("Start vector: ");
  vm_println(vects[0]);
  printf("Projecting start vector onto %d other vectors.\n", len - 1);
#endif

  if (len < 2){
    printf("Cannot project less than two vectors; num vects: %d\n", len);
  }

  vm_vector tmp;
  int i = 1;
  for ( ; i < len; i++){
    vm_project(vects[0], vects[i], &tmp);
    vm_print(vects[0]); printf(" p "); vm_print(vects[i]);
    printf(" = "); vm_println(tmp);
  }

}

void angle(vm_vector *vects, int len){

#ifdef _DEBUG
  printf("Start vector: ");
  vm_println(vects[0]);
  printf("Angling start vector with %d other vectors.\n", len - 1);
#endif

  if (len < 2){
    printf("Cannot angle less than two vectors; num vects: %d\n", len);
  }

  int i = 1;
  for ( ; i < len; i++){
    double d = vm_angle(vects[0], vects[i]);
    vm_print(vects[0]); printf(" A "); vm_print(vects[i]);
    printf(" = %fr\n", d);
  }

}

void print(vm_vector *vects, int len){

  int i = 0;
  for ( ; i < len; i++){
    vm_println(vects[i]);
  }

}
